import {
  BadRequestException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Order } from '../entities/order.entity';
import { RoomsService } from '../rooms/rooms.service';
import { UsersService } from '../users/users.service';
import { CreateOrderDto } from './dto/create-order.dto';
import { UpdateOrderDto } from './dto/update-order.dto';

@Injectable()
export class OrdersService {
  constructor(
    @InjectRepository(Order)
    private ordersRepository: Repository<Order>,
    private usersService: UsersService,
    private roomsService: RoomsService,
  ) {
    // 移除模拟数据初始化，避免外键约束错误
  }

  async findAll(): Promise<Order[]> {
    return this.ordersRepository.find({
      relations: ['user', 'room', 'room.hotel', 'payments'],
    });
  }

  async findOne(id: number): Promise<Order> {
    const order = await this.ordersRepository.findOne({
      where: { orderID: id },
      relations: ['user', 'room', 'payments'],
    });

    if (!order) {
      throw new NotFoundException(`未找到ID为${id}的订单`);
    }

    return order;
  }

  async findByUser(userId: number): Promise<Order[]> {
    return this.ordersRepository.find({
      where: { userId: userId },
      relations: ['room', 'payments'],
    });
  }

  async create(createOrderDto: CreateOrderDto): Promise<Order> {
    // 验证用户是否存在
    const user = await this.usersService.findOne(createOrderDto.userId);
    if (!user) {
      throw new NotFoundException(`未找到ID为${createOrderDto.userId}的用户`);
    }

    // 验证房间是否存在
    const room = await this.roomsService.findOne(createOrderDto.roomID);
    if (!room) {
      throw new NotFoundException(`未找到ID为${createOrderDto.roomID}的房间`);
    }

    // 验证日期是否合理
    const checkInDate = new Date(createOrderDto.checkInDate);
    const checkOutDate = new Date(createOrderDto.checkOutDate);

    console.log('处理日期 - 入住日期:', checkInDate);
    console.log('处理日期 - 离店日期:', checkOutDate);

    if (isNaN(checkInDate.getTime())) {
      throw new BadRequestException('请输入有效的入住日期');
    }

    if (isNaN(checkOutDate.getTime())) {
      throw new BadRequestException('请输入有效的离店日期');
    }

    if (checkOutDate <= checkInDate) {
      throw new BadRequestException('离店日期必须晚于入住日期');
    }

    // 检查房间是否在该时间段已被预订
    const conflictingOrders = await this.ordersRepository.find({
      where: { roomID: createOrderDto.roomID },
    });

    const hasConflict = conflictingOrders.some((order) => {
      const existingCheckIn = new Date(order.checkInDate);
      const existingCheckOut = new Date(order.checkOutDate);

      return (
        (checkInDate >= existingCheckIn && checkInDate < existingCheckOut) ||
        (checkOutDate > existingCheckIn && checkOutDate <= existingCheckOut) ||
        (checkInDate <= existingCheckIn && checkOutDate >= existingCheckOut)
      );
    });

    if (hasConflict) {
      throw new BadRequestException('该房间在所选时间段内已被预订');
    }

    const newOrder = this.ordersRepository.create(createOrderDto);
    return this.ordersRepository.save(newOrder);
  }

  async update(id: number, updateOrderDto: UpdateOrderDto): Promise<Order> {
    const order = await this.findOne(id);

    // 如果修改了用户ID，验证新用户是否存在
    if (updateOrderDto.userId && updateOrderDto.userId !== order.userId) {
      const user = await this.usersService.findOne(updateOrderDto.userId);
      if (!user) {
        throw new NotFoundException(`未找到ID为${updateOrderDto.userId}的用户`);
      }
    }

    // 如果修改了房间ID，验证新房间是否存在
    if (updateOrderDto.roomID && updateOrderDto.roomID !== order.roomID) {
      const room = await this.roomsService.findOne(updateOrderDto.roomID);
      if (!room) {
        throw new NotFoundException(`未找到ID为${updateOrderDto.roomID}的房间`);
      }

      // 如果更换了房间，需要检查新房间是否在该时间段已被预订
      const checkInDate = updateOrderDto.checkInDate
        ? new Date(updateOrderDto.checkInDate)
        : order.checkInDate;
      const checkOutDate = updateOrderDto.checkOutDate
        ? new Date(updateOrderDto.checkOutDate)
        : order.checkOutDate;

      const conflictingOrders = await this.ordersRepository.find({
        where: { roomID: updateOrderDto.roomID },
      });

      const hasConflict = conflictingOrders.some((existingOrder) => {
        // 跳过当前订单
        if (existingOrder.orderID === id) {
          return false;
        }

        const existingCheckIn = new Date(existingOrder.checkInDate);
        const existingCheckOut = new Date(existingOrder.checkOutDate);

        return (
          (checkInDate >= existingCheckIn && checkInDate < existingCheckOut) ||
          (checkOutDate > existingCheckIn &&
            checkOutDate <= existingCheckOut) ||
          (checkInDate <= existingCheckIn && checkOutDate >= existingCheckOut)
        );
      });

      if (hasConflict) {
        throw new BadRequestException('该房间在所选时间段内已被预订');
      }
    }

    // 如果修改了日期，验证新日期是否合理
    if (updateOrderDto.checkInDate && updateOrderDto.checkOutDate) {
      const checkInDate = new Date(updateOrderDto.checkInDate);
      const checkOutDate = new Date(updateOrderDto.checkOutDate);

      if (checkOutDate <= checkInDate) {
        throw new BadRequestException('离店日期必须晚于入住日期');
      }
    } else if (updateOrderDto.checkInDate) {
      const checkInDate = new Date(updateOrderDto.checkInDate);
      const checkOutDate = order.checkOutDate;

      if (checkOutDate <= checkInDate) {
        throw new BadRequestException('离店日期必须晚于入住日期');
      }
    } else if (updateOrderDto.checkOutDate) {
      const checkInDate = order.checkInDate;
      const checkOutDate = new Date(updateOrderDto.checkOutDate);

      if (checkOutDate <= checkInDate) {
        throw new BadRequestException('离店日期必须晚于入住日期');
      }
    }

    Object.assign(order, updateOrderDto);
    return this.ordersRepository.save(order);
  }

  async remove(id: number): Promise<void> {
    const result = await this.ordersRepository.delete(id);

    if (result.affected === 0) {
      throw new NotFoundException(`未找到ID为${id}的订单`);
    }
  }
}
